package net.es.oscars.utils.soap;

import java.lang.Exception;
import java.lang.NoSuchMethodException;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import net.es.oscars.common.soap.gen.OSCARSFaultMessage;
import net.es.oscars.common.soap.gen.OSCARSFault;

@SuppressWarnings ("serial")
public class OSCARSServiceException extends Exception {
    
    private Object faultInfo    = null;
    private String type = "unknown";
    
    public OSCARSServiceException (String message) {
        super(message);
    }
    
    public OSCARSServiceException(String message, String type) {
        super(message);
        this.setType(type);
    }
    public OSCARSServiceException (Exception e) {
        super(e.getMessage(),e);
        
        try {
            // Check if the exception object e is of a type generated by CXF or OSCARS and contains a FaultInfo.

            Method getFaultInfo = e.getClass().getMethod("getFaultInfo", (Class[]) null);
            try {
                if (e instanceof OSCARSFaultMessage) {
                    OSCARSFault of = (OSCARSFault) getFaultInfo.invoke(e, (Object[]) null);
                    this.type = of.getMsg();
                }  
                //might be a CXF class
                this.faultInfo = (Object) getFaultInfo.invoke(e, (Object[]) null);
                return;
            } catch (InvocationTargetException e1) {
                // Since the existence of the method is checked earlier, this error should never happen
            } catch (IllegalAccessException e2) {
                // Since the existence of the method is checked earlier, this error should never happen
            }
        } catch (NoSuchMethodException ee) {
            // This is a standard Exception - pass
        }
    }
    public OSCARSServiceException() {
        super();
    }
       
    public OSCARSServiceException(String message, Throwable cause) {
        super(message, cause);
    }

    
    public Object getFaultInfo () {
        return this.faultInfo;
    }
    public String getType () {
        return this.type;
    }
    
    public void setType (String type) {
        this.type = type;
    }
}
